package com.example.content_provider_client;

import android.annotation.SuppressLint;
import android.content.ContentProviderOperation;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.OperationApplicationException;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.RemoteException;
import android.provider.ContactsContract;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;

import com.example.content_provider_client.entity.ContactItem;

import java.util.ArrayList;

public class ContactsAdd extends AppCompatActivity implements View.OnClickListener {

    private TextView etName;
    private TextView etPhone;
    private TextView etEmail;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_contact_add);

        etName = findViewById(R.id.et_name);
        etPhone = findViewById(R.id.et_phone);
        etEmail = findViewById(R.id.et_email);

        findViewById(R.id.btn_add).setOnClickListener(this);
        findViewById(R.id.btn_find).setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        int id = view.getId();

        if (id == R.id.btn_add) {
            // 创建联系人对象
            ContactItem contact = new ContactItem();
            contact.name = etName.getText().toString();
            contact.phone = etPhone.getText().toString();
            contact.email = etEmail.getText().toString();

            // 1. 使用Content Resolve 多次写入，每次一个字段
            // addContacts(getContentResolver(), contact);

            // 2. 使用事务的方式添加联系人
            addContactsWithTransaction(getContentResolver(), contact);


        } else if (id == R.id.btn_find) {
            findContacts(getContentResolver());
        }
    }

    @SuppressLint("Range")
    private void findContacts(ContentResolver resolver) {
        // 查询raw_contacts表，获取_id，根据_id去data表中查询姓名，电话，邮箱
        Cursor cursor = resolver.query(
                ContactsContract.RawContacts.CONTENT_URI,
                new String[]{ContactsContract.RawContacts._ID},
                null,
                null
        );

        while (cursor.moveToNext()) {
            int rawContentId = cursor.getInt(0);
            Uri uri = Uri.parse("content://com.android.contacts/contacts/" + rawContentId + "/data");
            Cursor dataCursor = resolver.query(
                    uri,
                    new String[]{
                            ContactsContract.Contacts.Data.MIMETYPE,
                            ContactsContract.Contacts.Data.DATA1,
                            ContactsContract.Contacts.Data.DATA2
                    },
                    null,
                    null
            );

            ContactItem contact = new ContactItem();
            while (dataCursor.moveToNext()) {
                String data1 = dataCursor.getString(dataCursor.getColumnIndex(ContactsContract.Contacts.Data.DATA1));
                String mimetype = dataCursor.getString(dataCursor.getColumnIndex(ContactsContract.Contacts.Data.MIMETYPE));
                // 姓名
                if (mimetype.equals(ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)) {
                    contact.name = data1;
                } else if (mimetype.equals(ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)) {
                    contact.phone = data1;
                } else if (mimetype.equals(ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE)) {
                    contact.email = data1;
                }
            }
            dataCursor.close();
            Log.d("zhoutao", contact.toString());
        }
        cursor.close();
    }

    // 添加联系人使用事务的方式
    private void addContactsWithTransaction(ContentResolver resolver, ContactItem contact) {
        Log.d("zhoutao", "addContactsWithTransaction: ");
        ContentProviderOperation optMain = ContentProviderOperation
                // 向raw_contacts表中插入数据
                .newInsert(ContactsContract.RawContacts.CONTENT_URI)
                // 凑数的
                .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null)
                .build();

        ContentProviderOperation optName = ContentProviderOperation
                // 向data表中插入数据
                .newInsert(ContactsContract.Data.CONTENT_URI)
                // 向data表中插入一条数据，设置列 raw_contact_id，raw_contact_id为optMain操作的结果，其实也没说清楚，反正就这样用
                .withValueBackReference(ContactsContract.Contacts.Data.RAW_CONTACT_ID, 0)
                // 向data表中插入一条数据，设置列 mimetype的值
                .withValue(ContactsContract.Contacts.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
                // 向data表中插入一条数据，设置列 data2的值为姓名
                .withValue(ContactsContract.Contacts.Data.DATA2, contact.name)
                .build();

        ContentProviderOperation optPhone = ContentProviderOperation
                // 向data表中插入数据
                .newInsert(ContactsContract.Data.CONTENT_URI)
                // 向data表中插入一条数据，设置列 raw_contact_id，raw_contact_id为optMain操作的结果，其实也没说清楚，反正就这样用
                .withValueBackReference(ContactsContract.Contacts.Data.RAW_CONTACT_ID, 0)
                // 向data表中插入一条数据，设置列 mimetype的值
                .withValue(ContactsContract.Contacts.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
                // 向data表中插入一条数据，设置列 data1的值为号码
                .withValue(ContactsContract.Contacts.Data.DATA1, contact.phone)
                // 向data表中插入一条数据，设置列 data2的值为(DATA1)号码类型，设置为手机号
                .withValue(ContactsContract.Contacts.Data.DATA2, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE)
                .build();

        ContentProviderOperation optEmail = ContentProviderOperation
                // 向data表中插入数据
                .newInsert(ContactsContract.Data.CONTENT_URI)
                // 向data表中插入一条数据，设置列 raw_contact_id，raw_contact_id为optMain操作的结果，其实也没说清楚，反正就这样用
                .withValueBackReference(ContactsContract.Contacts.Data.RAW_CONTACT_ID, 0)
                // 向data表中插入一条数据，设置列 mimetype的值
                .withValue(ContactsContract.Contacts.Data.MIMETYPE, ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE)
                // 向data表中插入一条数据，设置列 data1的值为电子邮件
                .withValue(ContactsContract.Contacts.Data.DATA1, contact.email)
                // 向data表中插入一条数据，设置列 data2的值为(DATA1)邮箱类型，设置为工作
                .withValue(ContactsContract.Contacts.Data.DATA2, ContactsContract.CommonDataKinds.Email.TYPE_WORK)
                .build();

        ArrayList<ContentProviderOperation> operations = new ArrayList<>();
        operations.add(optMain);
        operations.add(optName);
        operations.add(optPhone);
        operations.add(optEmail);

        try {
            // 批量添加联系人，姓名，号码，email，并且使用事务
            resolver.applyBatch(ContactsContract.AUTHORITY, operations);
        } catch (OperationApplicationException e) {
            throw new RuntimeException(e);
        } catch (RemoteException e) {
            throw new RuntimeException(e);
        }
    }

    // 添加一个联系人到手机通讯录，
    private void addContacts(ContentResolver resolver, ContactItem contact) {

        Log.d("zhoutao", contact.toString());

        // 1.先插入一条联系人记录到row_contacts表，得到row_contacts，用于data表添加数据的时候使用
        // row_contacts表的uri
        Uri rawContactsUri = ContactsContract.RawContacts.CONTENT_URI;
        // 插入一条空的记录
        ContentValues values = new ContentValues();
        // row_contacts表插入新的联系人会返回一条uri，uri中包含id
        Uri newRawContactUri = resolver.insert(rawContactsUri, values);
        // 新联系人记录的id
        long rawContactId = ContentUris.parseId(newRawContactUri);

        // 2. data表中插入上面联系人记录的 raw_contact_id, mimetype,

        // data表的uri
        Uri dataUri = ContactsContract.Data.CONTENT_URI;
        // data表raw_contact_id列名
        String fieldRawContactId = ContactsContract.Contacts.Data.RAW_CONTACT_ID;

        // data表mimetype列名
        String fieldMimetype = ContactsContract.Contacts.Data.MIMETYPE;
        // 姓名的mime-type: vnd.android.cursor.item/name
        String mimeName = ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE;

        // data表data2列名
        String fieldData2 = ContactsContract.Contacts.Data.DATA2;

        ContentValues name = new ContentValues();
        // 设置raw_contact_id
        name.put(fieldRawContactId, rawContactId);
        // 设置mimetype
        name.put(fieldMimetype, mimeName);
        // 设置data2，即 姓名
        name.put(fieldData2, contact.name);

        // 3. 插入姓名到data表
        resolver.insert(dataUri, name);

        // 4. 插入号码到data表
        ContentValues phone = new ContentValues();
        // 设置设置raw_contact_id，
        phone.put(fieldRawContactId, rawContactId);
        // 设置手机号码的mimetype
        String mimeMobile = ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE;
        phone.put(fieldMimetype, mimeMobile);
        // 设置手机号到data表的data1列（字段）,ContactsContract.Contacts.Data.DATA1
        phone.put(ContactsContract.Contacts.Data.DATA1, contact.phone);
        // 设置联系类型到data2字段，联系类型为手机号TYPE_MOBILE
        int typeMobile = ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE;
        phone.put(ContactsContract.Contacts.Data.DATA2, typeMobile);

        // 插入手机号到data表
        resolver.insert(dataUri, phone);

        // 5. 插入邮箱
        ContentValues email = new ContentValues();
        // 设置raw_contact_id
        email.put(fieldRawContactId, rawContactId);
        // 设置邮箱的mimetype
        String mimeEmail = ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE;
        email.put(fieldMimetype, mimeEmail);
        // 设置邮箱地址到 data表的data1字段
        email.put(ContactsContract.Contacts.Data.DATA1, contact.email);
        // 设置data2字段，data2字段值为描述data1字段（邮箱地址）的类型，比如类型是工作邮箱
        int emailType = ContactsContract.CommonDataKinds.Email.TYPE_WORK;
        email.put(ContactsContract.Contacts.Data.DATA2, emailType);

        // 插入邮箱到data表
        resolver.insert(dataUri, email);
    }


}